#include "CParticleManager.h"
#include "SGD Wrappers/CSGD_TextureManager.h"
#include "SGD Wrappers/CSGD_Direct3D.h"
#include "CEmitter.h"
#include <fstream>
#include <iostream>


CParticleManager::CParticleManager()
{
	m_nEmitterCount = 0;
}
CParticleManager::~CParticleManager()
{
}
CParticleManager* CParticleManager::GetInstance()
{
	static CParticleManager instance;
	return &instance;
}
void CParticleManager::Init()
{

}
void CParticleManager::Clear()
{
	for(int i = 0; i < m_nEmitterCount; ++i)
	{
		if(m_vecEmitters.size() > 0)
		{
			m_vecEmitters[0]->ClearLists();
			delete m_vecEmitters[0];
			m_vecEmitters[0] = NULL;
			m_vecEmitters.erase(m_vecEmitters.begin());
		}
		else
			break;
		
	}
	m_vecEmitters.clear();
}
void CParticleManager::Shutdown()
{
	Clear();
}
CEmitter* CParticleManager::AddEmitter(int posX, int posY, const char* szFilePath)
{
	ifstream fin(szFilePath, std::ios_base::binary);
	fin.exceptions(~std::ios_base::goodbit);
	try
	{
		CEmitter* pEmitter = new CEmitter;
		char szFile[256];
		unsigned int byteStrLen = 0;
		unsigned int byteStrLenCon = 0;
		D3DXCOLOR scolor;
		D3DXCOLOR ecolor;
		

		fin.read((char*)&byteStrLen, sizeof(char));
		fin.clear();
		if(byteStrLen >= 127)
		{
			fin.read((char*)&byteStrLenCon, sizeof(char));
			fin.clear();
		}
		memset(szFile, 0, byteStrLen + byteStrLenCon);
		fin.read(szFile, byteStrLen + byteStrLenCon);
		fin.clear();
		szFile[byteStrLen+byteStrLenCon] = 0;
		char buffer[256];
		//Image
  		sprintf_s(buffer,_countof(buffer), "Resource/Particles/%s", szFile);
		pEmitter->SetImage(CSGD_TextureManager::GetInstance()->LoadTexture(buffer));
		//Number of Particles
		int numPart;
		fin.read((char*)&numPart, sizeof(int));
		fin.clear();
		pEmitter->SetNumParticle(numPart);
		//Minimum X Velocity
		float minXvel;
		fin.read((char*)&minXvel, sizeof(float));
		fin.clear();
		pEmitter->SetMinXVel(minXvel);
		//Maximum X Velocity
		float maxXvel;
		fin.read((char*)&maxXvel, sizeof(float));
		fin.clear();
		pEmitter->SetMaxXVel(maxXvel);
		//Minimum Y Velocity
		float minYvel;
		fin.read((char*)&minYvel, sizeof(float));
		fin.clear();
		pEmitter->SetMinYVel(minYvel);
		//Maximum Y Velocity
		float maxYvel;
		fin.read((char*)&maxYvel, sizeof(float));
		fin.clear();
		pEmitter->SetMaxYVel(maxYvel);
		//Minimum Lifespan
		int minLife;
		fin.read((char*)&minLife, sizeof(int));
		fin.clear();
		pEmitter->SetMinLife(minLife);
		//Maximum Lifespan
		int maxLife;
		fin.read((char*)&maxLife, sizeof(int));
		fin.clear();
		pEmitter->SetMaxLife(maxLife);
		//Scale
		float scale;
		fin.read((char*)&scale, sizeof(float));
		fin.clear();
		pEmitter->SetScale(scale);
		//X Gravity
		float Xgrav;
		fin.read((char*)&Xgrav, sizeof(float));
		fin.clear();
		pEmitter->SetXGrav(Xgrav);
		//Y Gravity
		float Ygrav;
		fin.read((char*)&Ygrav, sizeof(float));
		fin.clear();
		pEmitter->SetYGrav(Ygrav);
		//Starting Color
		//	Alpha
		float alpha;
		fin.read((char*)&alpha, sizeof(float));
		fin.clear();
		scolor.a = alpha;
		//	Red
		float red;
		fin.read((char*)&red, sizeof(float));
		fin.clear();
		scolor.r = red;
		//	Green
		float green;
		fin.read((char*)&green, sizeof(float));
		fin.clear();
		scolor.g = green;
		//	Blue
		float blue;
		fin.read((char*)&blue, sizeof(float));
		fin.clear();
		scolor.b = blue;
		pEmitter->SetStartColor(scolor);
		//Ending Color
		//	Alpha
		float Ealpha;
		fin.read((char*)&Ealpha, sizeof(float));
		fin.clear();
		ecolor.a = Ealpha;
		//	Red
		float Ered;
		fin.read((char*)&Ered, sizeof(float));
		fin.clear();
		ecolor.r = Ered;
		//	Green
		float Egreen;
		fin.read((char*)&Egreen, sizeof(float));
		fin.clear();
		ecolor.g = Egreen;
		//	Blue
		float Eblue;
		fin.read((char*)&Eblue, sizeof(float));
		fin.clear();
		ecolor.b = Eblue;
		pEmitter->SetEndColor(ecolor);
		//Soucre Blending
		int sourceblend;
		fin.read((char*)&sourceblend, sizeof(int));
		fin.clear();
		pEmitter->SetStartBlend((unsigned int)sourceblend);
		//Destination Blending
		int destBlend;
		fin.read((char*)&destBlend, sizeof(int));
		fin.clear();
		pEmitter->SetDestBlend((unsigned int)destBlend);
		//Emission Rate
		float emissionRate;
		fin.read((char*)&emissionRate, sizeof(float));
		fin.clear();
		pEmitter->SetEmissionRate(emissionRate);
		//Circle Effect
		bool spread;
		fin.read((char*)&spread, sizeof(bool));
		fin.clear();
		pEmitter->SetSpread(spread);
		fin.close();
		pEmitter->SetPosX((float)posX);
		pEmitter->SetPosY((float)posY);
		m_vecEmitters.push_back(pEmitter);
		m_nEmitterCount += 1;
		return pEmitter;
	}
	catch(std::ios_base::failure)
	{
		fin.close();
		MessageBox(NULL,
			"File Read Error","Error",MB_OK);
		return NULL;
	}
}
void CParticleManager::RemoveEmitter(CEmitter *pEmitter)
{
	vector<CEmitter*>::iterator iter = m_vecEmitters.begin();
	for(unsigned int i = 0; i < m_vecEmitters.size(); ++i)
	{
		
		if(pEmitter == m_vecEmitters[i])
		{
			m_vecEmitters[i]->ClearLists();
			delete m_vecEmitters[i];
			m_vecEmitters[i] = NULL;
				
			m_vecEmitters.erase(iter);
			break;
		}
		++iter;
	}
}
void CParticleManager::Update(float fDelta)
{
	for(unsigned int i = 0; i < m_vecEmitters.size(); ++i)
	{
		m_vecEmitters[i]->Update(fDelta);
	}
}
void CParticleManager::Render()
{
	for(unsigned int i = 0; i < m_vecEmitters.size(); ++i)
	{
		m_vecEmitters[i]->Render();
	}
}